package com.canbot.u05.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.canbot.u05.R;

/**
 * Created by zmp on 2017/9/20.
 */

public class MyLeftRockerView extends View {

        public static final String TAG = "MyLeftRockerView";

        private int width;

        private int height;

        private int maxR;

        private float outR;

        private float innerR;

        private GestureDetector mGestureDetector;

        private float maxInnerR;

        private Paint strokePaint;

        private Bitmap scaledOutBitmap;

        private Bitmap bitmap;

        private Bitmap rockerBitmap;

        private Bitmap scaledRockerBitmap;

        public MyLeftRockerView(Context context) {
                this(context, null);
        }

        public MyLeftRockerView(Context context, @Nullable AttributeSet attrs) {
                this(context, attrs, 0);
        }

        public MyLeftRockerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                init();
        }

        private void init() {
                mGestureDetector = new GestureDetector(getContext(), onGestureListener);
                strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                strokePaint.setStyle(Paint.Style.STROKE);
                strokePaint.setColor(Color.WHITE);

                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.view_big);

                rockerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.view_small);
        }

        public void setBackgroundBitmapID(int id) {
                bitmap = BitmapFactory.decodeResource(getResources(), id);
                scaledOutBitmap = null;
                invalidate();
        }

        public void setRockerBitmapID(int id) {
                rockerBitmap = BitmapFactory.decodeResource(getResources(), id);
                scaledRockerBitmap = null;
                invalidate();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
                int action = event.getAction();
                if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                        innerX = width / 2;
                        innerY = height / 2;
                        invalidate();
                        removeCallbacks(pressRunnable);
                        if (rockerListener != null) {
                                rockerListener.onUpOrCancel();
                        }
                }
                mGestureDetector.onTouchEvent(event);
                return true;
        }

        private float innerY;

        private float innerX;

        GestureDetector.OnGestureListener onGestureListener = new GestureDetector.OnGestureListener() {
                @Override
                public boolean onDown(MotionEvent motionEvent) {
                        float x = motionEvent.getX();
                        float y = motionEvent.getY();
                        invalidateInnerXY(x, y);
                        postDelayed(pressRunnable, 100);
                        if (rockerListener != null) {
                                rockerListener.onDown(listenTouch(x, y));
                        }
                        return false;
                }

                @Override
                public void onShowPress(MotionEvent motionEvent) {
                        Log.e(TAG, "onShowPress");
                }

                @Override
                public boolean onSingleTapUp(MotionEvent motionEvent) {
                        return false;
                }

                @Override
                public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
                        float x = motionEvent1.getX();
                        float y = motionEvent1.getY();
                        invalidateInnerXY(x, y);
                        if (rockerListener != null) {
                                rockerListener.onScroll(listenTouch(x, y));
                        }
                        return false;
                }

                @Override
                public void onLongPress(MotionEvent motionEvent) {
                        Log.e(TAG, "onLongPress");
                }

                @Override
                public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
                        Log.e(TAG, "onFling");
                        return false;
                }
        };

        public void setPressReFreshTime(long pressReFreshTime) {
                this.pressReFreshTime = pressReFreshTime;
        }

        private long pressReFreshTime = 200;

        Runnable pressRunnable = new Runnable() {
                @Override
                public void run() {
                        if (rockerListener != null) {
                                rockerListener.onPress(listenTouch(innerX, innerY));
                        }
                        Log.e(TAG, "pressRunnable");
                        postDelayed(pressRunnable, pressReFreshTime);
                }
        };

        private double listenTouch(float x, float y) {
                float dX = (x - width / 2);
                float dY = (y - height / 2);
                double a = Math.atan(dY / dX);
                Log.d(TAG, a * 180 / Math.PI + "");
                if (dX > 0) {
                        a = Math.PI + a;
                }
                else {
                        if (dY > 0) {
                                a = Math.PI * 2 + a;
                        }
                }
                Log.d(TAG, a * 180 / Math.PI + "");
                return a;

        }

        private void invalidateInnerXY(float x, float y) {
                float dX = (x - width / 2);
                float dY = (y - height / 2);
                if (dX * dX + dY * dY < maxInnerR * maxInnerR) {
                        innerX = x;
                        innerY = y;
                        invalidate();
                        return;
                }
                double ratio = maxInnerR / Math.sqrt(dX * dX + dY * dY);
                innerX = (float) (ratio * (x - width / 2)) + width / 2;
                innerY = (float) (ratio * (y - height / 2)) + height / 2;
                invalidate();

        }

        @Override
        protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                if (scaledOutBitmap == null) {
                        scaledOutBitmap = Bitmap.createScaledBitmap(bitmap, (int) (outR * 2), (int) (outR * 2), false);
                        bitmap.recycle();
                }
                if (scaledRockerBitmap == null) {
                        scaledRockerBitmap = Bitmap.createScaledBitmap(rockerBitmap, (int) (innerR * 2), (int) (innerR * 2), false);
                }
                canvas.drawBitmap(scaledOutBitmap, width / 2 - outR, height / 2 - outR, null);
                canvas.drawBitmap(scaledRockerBitmap, innerX - innerR, innerY - innerR, null);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                super.onSizeChanged(w, h, oldw, oldh);
                width = getMeasuredWidth();
                height = getMeasuredHeight();
                maxR = width;
                if (width > height) {
                        maxR = height;
                }
                outR = maxR * 0.48f;
                innerR = maxR * 0.15f;
                maxInnerR = outR - innerR;
                maxInnerR *= 0.74;
                innerX = width / 2;
                innerY = height / 2;
        }

        public void setRockerListener(ILeftRockerListener rockerListener) {
                this.rockerListener = rockerListener;
        }

        private ILeftRockerListener rockerListener;

        public interface ILeftRockerListener {

                void onDown(double angle);

                void onPress(double angle);

                void onScroll(double angle);

                void onUpOrCancel();
        }

        public static class LeftRockerListenerAdapter implements ILeftRockerListener {

                @Override
                public void onDown(double angle) {

                }

                @Override
                public void onPress(double angle) {

                }

                @Override
                public void onScroll(double angle) {

                }

                @Override
                public void onUpOrCancel() {

                }
        }
}
